package Controllers;

import Information.PostInfo;
import Information.UserInfo;
import Application.ReadFileToString;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

/**
 * @author MinamiKotori
 */
public class PostSiteController extends Application implements Initializable {
    @FXML
    private Label time;                 //文章时间
    @FXML
    private Label tag;                  //文章标签
    @FXML
    private Label postTitle;            //文章标题
    @FXML
    private TextArea postContent;       //文章正文
    @FXML
    private ImageView authorAvatar;     //作者头像
    @FXML
    private Label authorName;           //作者昵称
    @FXML
    private Label authorFans;           //粉丝数
    @FXML
    private Button subscribe;           //订阅按钮
    @FXML
    private ImageView collect;          //收藏按钮
    @FXML
    private Label collectNum;           //收藏数
    @FXML
    private ImageView like;             //点赞按钮
    @FXML
    private Label likeNum;              //点赞数
    @FXML
    private ImageView comment;          //评论按钮
    @FXML
    private Label commentNum;           //评论数
    @FXML
    private ImageView share;            //分享按钮
    @FXML
    private Label shareNum;             //分享数

    /**
     * 备份需要用到的三个Info对象
     */
    private PostInfo postInfo;
    private UserInfo authorInfo;
    private UserInfo userInfo;

    /**
     * 评论区窗口
     */
    private Stage commentStage;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //得到对象
        this.readCurrentObject();

        //初始化帖子
        this.loadPost();
    }

    /**
     * 读取出三个Info对象
     */
    public void readCurrentObject() {
        try (
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src/UserPosts/currentPost.ser"))
        ) {
            //得到对象
            postInfo = (PostInfo) ois.readObject();
            //得到用户对象
            try {
                String authorPath = "src/UserPosts/userObjects/" + postInfo.getAuthorId() + ".ser";
                String userPath = "src/UserPosts/currentUser.ser";
                ObjectInputStream oisAuthor = new ObjectInputStream(new FileInputStream(authorPath));
                ObjectInputStream oisUser = new ObjectInputStream(new FileInputStream(userPath));
                authorInfo = (UserInfo) oisAuthor.readObject();
                userInfo = (UserInfo) oisUser.readObject();
                oisAuthor.close();
                oisUser.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据当前Info选取对应图标
     */
    public void setIcon() {
        //设置不同图标
        if (this.getIndexInArray(postInfo.getLikedByUserID(), userInfo) < 0) {
            like.setImage(new Image("Images/like.png"));
        } else {
            like.setImage(new Image("Images/likeFilled.png"));
        }

        if (this.getIndexInArray(postInfo.getCommentedByUserID(), userInfo) < 0) {
            comment.setImage(new Image("Images/comment.png"));
        } else {
            comment.setImage(new Image("Images/commentFilled.png"));
        }

        if (this.getIndexInArray(postInfo.getCollectedByUserID(), userInfo) < 0) {
            collect.setImage(new Image("Images/collect.png"));
        } else {
            collect.setImage(new Image("Images/collectFilled.png"));
        }

        //设置关注按钮文字
        if (this.getIndexInArray(userInfo.getFollowID(), authorInfo) < 0) {
            subscribe.setText("关注");
        } else {
            subscribe.setText("已关注");
        }
    }

    /**
     * 加载当前的postInfo
     */
    public void loadPost() {
        //设置图标
        this.setIcon();

        //初始化界面数据
        time.setText(postInfo.getCreatedTime());
        tag.setText(postInfo.getTag());
        likeNum.setText(String.valueOf(postInfo.getLikes()));
        commentNum.setText(String.valueOf(postInfo.getComments()));
        collectNum.setText(String.valueOf(postInfo.getCollections()));
        shareNum.setText(String.valueOf(postInfo.getShares()));

        //设置作者信息
        authorName.setText(authorInfo.getPname());
        authorAvatar.setImage(new Image(authorInfo.getAvatar()));
        authorFans.setText("粉丝:" + authorInfo.getFansNum());

        //设置文字
        postTitle.setText(ReadFileToString.readFile(postInfo.getTitlePath()));
        postContent.setText(ReadFileToString.readFile(postInfo.getTextPath()));
    }

    @Override
    public void start(Stage primaryStage){
        try {
            Parent root = FXMLLoader.load(getClass().getResource("../Resources/PostSite.fxml"));
            Scene scene = new Scene(root, 1300, 850);
            primaryStage.getIcons().add(new Image("/Images/logoblue.png"));

            primaryStage.setScene(scene);
            primaryStage.setTitle("帖子");
            primaryStage.setResizable(false);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void authorInfo(MouseEvent mouseEvent) {
//        //打开作者信息
//        UserSiteController userSite = new UserSiteController();
//        try {
//            userSite.start(new Stage());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

    }

    /**
     * 判断给定的用户id是否在给定array中出现
     * @param arrayList 传入存放ID的数组进行操作
     * @param userInfo 需要判断的用户id
     * @return 出现就返回第一次出现时的下标，否则为-1
     */
    public int getIndexInArray(ArrayList<String> arrayList, UserInfo userInfo) {
        if (arrayList.size() == 0) {
            return -1;
        }

        int i;
        //判断是否出现的标志位
        boolean flag = false;
        //遍历数组中的用户id与当前id进行比较
        for (i = 0; i < arrayList.size(); i++) {
            if (userInfo.getId().equals(arrayList.get(i))) {
                flag = true;
                break;
            }
        }
        //判断返回的下标
        if (flag) {
            return i;
        } else {
            return -1;
        }
    }

    /**
     * 判断当前帖子是否在用户收藏列表中出现
     * @param arrayList 用户收藏帖子的数组
     * @return 出现就返回第一次出现时的下标，否则为-1
     */
    public int getIndexInUserArray(ArrayList<String> arrayList) {
        if (arrayList.size() == 0) {
            return -1;
        }

        int i;
        //判断是否出现的标志位
        boolean flag = false;
        //遍历数组中的帖子id与当前帖子id进行比较
        for (i = 0; i < arrayList.size(); i++) {
            if (postInfo.getPostId().equals(arrayList.get(i))) {
                flag = true;
                break;
            }
        }
        //判断返回的下标
        if (flag) {
            return i;
        } else {
            return -1;
        }
    }

    /**
     * 把更改过的当前对象的postInfo写入文件
     */
    public void writePostInfo() {
        String path = "src/UserPosts/postObjects/" + postInfo.getPostId() + ".ser";
        String currentPath = "src/UserPosts/currentPost.ser";
        try(
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
                ObjectOutputStream oosCurrent = new ObjectOutputStream(new FileOutputStream(currentPath))
        ) {
            //写入当前帖子对象
            oos.writeObject(postInfo);
            oosCurrent.writeObject(postInfo);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 把当前用户写入currentUser和本身
     */
    public void writeCurrentInfo() {
        //得到路径
        String userInfoPath = "src/UserPosts/userObjects/" + userInfo.getId() + ".ser";
        String currentInfoPath = "src/UserPosts/currentUser.ser";

        //写入currentInfo和userInfo
        try (
                ObjectOutputStream objectOutputStreamUser = new ObjectOutputStream(new FileOutputStream(userInfoPath));
                ObjectOutputStream objectOutputStreamCurrent = new ObjectOutputStream(new FileOutputStream(currentInfoPath))
        ) {
            objectOutputStreamUser.writeObject(userInfo);
            objectOutputStreamCurrent.writeObject(userInfo);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 把更新过的作者信息写入文件
     */
    public void writeAuthorInfo() {
        //得到路径
        String authorInfoPath = "src/UserPosts/userObjects/" + authorInfo.getId() + ".ser";

        //写入authorInfo和userInfo
        try (
                ObjectOutputStream objectOutputStreamAuthor = new ObjectOutputStream(new FileOutputStream(authorInfoPath))
        ) {
            objectOutputStreamAuthor.writeObject(authorInfo);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void like(MouseEvent mouseEvent) {
        //得到的数组信息
        ArrayList<String> arrayList = postInfo.getLikedByUserID();
        int index = getIndexInArray(arrayList, userInfo);
        //已有下标就取消，否则在后面添加id
        if (index >= 0) {
            arrayList.remove(index);
        } else {
            arrayList.add(userInfo.getId());
        }
        this.setIcon();
        //更新Label
        likeNum.setText(String.valueOf(arrayList.size()));
        postInfo.setLikedByUserID(arrayList);
        postInfo.setLikes(arrayList.size());
        //写入文件
        this.writePostInfo();
    }

    public void comment(MouseEvent mouseEvent) {
        //将当前帖子对象写入current，呼出帖子窗口
        this.writePostInfo();

        //打开评论区窗口
        PostCommentController postComments = new PostCommentController();
        commentStage = new Stage();
        //给窗口绑定关闭监听器，关闭后自动本页面重新加载帖子内容
        commentStage.setOnCloseRequest(event -> {
            //关闭后初始化界面
            this.readCurrentObject();
            this.loadPost();
        });
        postComments.start(commentStage);
    }

    public void collect(MouseEvent mouseEvent) {
        //帖子的被收藏数组
        ArrayList<String> arrayList = postInfo.getCollectedByUserID();
        int index = getIndexInArray(arrayList, userInfo);
        //用户的收藏数组
        ArrayList<String> arrayListUser = userInfo.getCollectPostID();
        int indexUser = getIndexInUserArray(arrayListUser);

        //已有下标就取消，否则在后面添加id
        if (index >= 0) {
            //帖子列表中移除
            arrayList.remove(index);
            //在用户列表中一并取消
            if (indexUser >= 0) {
                arrayListUser.remove(indexUser);
            }
        } else {
            //帖子列表中增加
            arrayList.add(userInfo.getId());
            //在用户收藏列表中增加当前帖子
            if (indexUser < 0) {
                arrayListUser.add(postInfo.getPostId());
            }
        }
        this.setIcon();
        //更新对象
        postInfo.setCollectedByUserID(arrayList);
        postInfo.setCollections(arrayList.size());
        userInfo.setCollectPostID(arrayListUser);
        //更新Label
        collectNum.setText(String.valueOf(arrayList.size()));

        //写入文件
        this.writePostInfo();
        this.writeCurrentInfo();
    }

    public void share(MouseEvent mouseEvent) {
        ArrayList<String> arrayList = postInfo.getSharedByUserID();
        int index = getIndexInArray(arrayList, userInfo);
        //已有下标就取消，否则在后面添加id
        if (index >= 0) {
            arrayList.remove(index);
        } else {
            arrayList.add(userInfo.getId());
        }
        //更新Label
        shareNum.setText(String.valueOf(arrayList.size()));
        postInfo.setSharedByUserID(arrayList);
        postInfo.setShares(arrayList.size());
        //写入文件
        this.writePostInfo();
    }

    public void onSubscribeClicked(ActionEvent actionEvent) {
        //我 关 注 我 自 己
        if (userInfo.getId().equals(authorInfo.getId())) {
            String info = "不能关注自己";
            Alert alert = new Alert(Alert.AlertType.INFORMATION, info, new ButtonType("确定", ButtonBar.ButtonData.YES));
            alert.setHeaderText(null);
            alert.setTitle("提示");
            alert.show();
            return;
        }

        //得到的数组信息
        ArrayList<String> followArrayList = userInfo.getFollowID();
        ArrayList<String> fansArrayList = authorInfo.getFansID();
        int followIndex = getIndexInArray(followArrayList, authorInfo);
        int fansIndex = getIndexInArray(fansArrayList, userInfo);

        //已有下标就取消，否则在后面添加id
        if (followIndex >= 0) {
            //关注列表移除作者id
            followArrayList.remove(followIndex);
            //作者粉丝列表移除用户id
            if (fansIndex >= 0) {
                fansArrayList.remove(fansIndex);
            }
            //取消之后设置按钮文字
            subscribe.setText("关注");
        } else {
            //关注列表中增加作者id
            followArrayList.add(authorInfo.getId());
            //作者粉丝列表中增加用户id
            if (fansIndex < 0) {
                authorInfo.getFansID().add(userInfo.getId());
            }
            //设置按钮文字
            subscribe.setText("已关注");
        }
        //更新对象
        authorInfo.setFansID(fansArrayList);
        authorInfo.setFansNum(fansArrayList.size());
        userInfo.setFollowID(followArrayList);
        userInfo.setFollowNum(followArrayList.size());

        //更新Label
        authorFans.setText("粉丝:" + authorInfo.getFansNum());

        //写入用户信息
        this.writeAuthorInfo();
        this.writeCurrentInfo();
    }
}
